<!-- 需求：1.改时间和信息一个弹窗，时间条只改开始时间 时间间隔不变 ，2.改完时间如果出现最大最小值 时间条要改变，3.绿点要加入弹窗，4.echart需要动画， -->

<template>
  <div>
    <div style="margin-bottom: 30px;">
      自定义时间:
      <el-time-select
        v-model="startTime"
        placeholder="起始时间"
        :picker-options="{
          start: '00:00',
          step: '01:00',
          end: '23:59',
        }"
      />
      <el-time-select
        v-model="endTime"
        placeholder="结束时间"
        :picker-options="{
          start: '00:00',
          step: '01:00',
          end: '23:59',
        }"
        @change="changeEndTime"
      />
      <el-select v-model="timeInterval" placeholder="请选择" @change="timeIntervalchange">
        <el-option
          v-for="item in timeIntervalOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
      <span>{{ startTime }}-{{ endTime }}</span>
      <span>分钟数：{{ totalMin }}@@@@{{ perMin }}</span>
    </div>
    <div class="slide-ruler">
      <div v-for="time of timeList" :key="time" class="scale">{{ time }}</div>
    </div>
    <draggable
      v-model="rows"
      class="row sortable-list"
      animation="300"
      handle=".mover"
      @end="end"
    >

      <div
        v-for="(row,index) in rows"
        :key="row.index"
        class="sortable"
        @click.stop="clickChoose(row) "
      >
        <span class="mover">+</span>
        <span>{{ index+1 }}</span>
        <div class="slide-list">
          <div class="slide-ruler-item">
            <div v-for="time of timeList" :key="time" class="scale-item" />
          </div>
          <div ref="slideBox" class="slide-box">
            <draggable
              :list="row.items"
              :group="{ name: 'row' }"
              class="row-item"
              :move="onMove"
              handle=".mover-item"
              @start="start($event,rows)"
              @end="end(rows)"
            >
              <div
                v-for="(item, key) of row.items"
                :key="item.id"
                ref="slideBoxItem"
                class="slide-box-item"
                :style="`width: ${item.width}%; left: ${item.left}%; background: ${itemBGcolor[ key % 2 ]}`"
                @click.stop="timeBlock(row.fid, key, item)"
              >
                <div class="mover-item">{{ item.id }}
                  <div
                    v-for="(siteItem) of item.site"
                    :key="siteItem.id"
                    class="mover-item-site"
                    :style="`left: ${siteItem.left}%;`"
                  />
                </div>
              </div>

            </draggable>
          </div>
        </div>
      </div>
    </draggable>
    <div style="margin-top: 30px;">{{ rows }}</div>
    <el-dialog
      title="提示"
      :visible.sync="dialogVisible"
      width="30%"
      :modal="false"
    >
      <span>这是一段信息</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>
<script>
import draggable from 'vuedraggable'
import BigNumber from 'bignumber.js'
import dayjs from 'dayjs'

export default {
  name: 'TwoLists',
  display: 'Two Lists',
  order: 1,
  components: {
    draggable
  },
  data() {
    return {
      startTime: '08:00',
      endTime: '17:00',
      rows: [],
      // 时间刻度（小时）
      timeList: [],
      // 左右i的显示
      iShow: null,
      // 是否是选中的时间子块
      loop: null,
      // 存根数据
      stubData: {},
      // 时间间隔颜色
      itemBGcolor: ['#DAA520', '#B22222'],
      // 总分钟
      totalMin: 0,
      // 每分钟
      perMin: 0,
      timeIntervalOptions: [{
        value: '60',
        label: '小时'
      }, {
        value: '30',
        label: '半小时'
      }, {
        value: '15',
        label: '15分钟'
      }],
      timeInterval: '60',
      dialogVisible: false,
      itemTime: {
        startTime: '',
        endTime: ''
      }
    }
  },
  created() {
    this.getData()
  },
  methods: {
    getData() {
      this.changeEndTime()
      this.totalMin = this.getMinutesBetween(this.startTime, this.endTime)
      this.rows = [
        {
          index: 1,
          fid: 0,
          items: [
            { id: '001',
              startTime: '08:30',
              endTime: '09:50',
              'changeTimeShow': false,
              site: [
                {
                  id: '2357',
                  disMin: '20'
                },
                {
                  id: '2358',
                  disMin: '60'
                }
              ]
            }

          ]
        },
        {
          index: 2,
          fid: 1,
          items: [
            { id: '002',
              'changeTimeShow': false,
              startTime: '09:00',
              endTime: '10:11',
              site: [
                {
                  id: '2327',
                  disMin: '10'
                },
                {
                  id: '2328',
                  disMin: '30'
                }
              ]
            },
            { id: '003',
              'changeTimeShow': false,
              startTime: '10:20',
              endTime: '12:58',
              site: [
                {
                  id: '2337',
                  disMin: '20'
                }
              ]
            }
          ]
        }
      ]
      this.checkTimeComparison(this.startTime, this.endTime, this.rows)
      this.initData()
      const startTime = '2023-10-23 08:00'
      const endTime = '2023-10-23 22:00'
      const timeArray_60 = this.generateTimeArray(startTime, endTime, 60)
      // const timeArray_30 = this.generateTimeArray(startTime, endTime, 30)
      // const timeArray_15 = this.generateTimeArray(startTime, endTime, 15)

      console.log(timeArray_60)
      console.log(this.startAndend())
      console.log(this.getMinBetween())
    },
    // 初始数据过滤
    async initData() {
      // 检查是否有满足条件的startTime和endTime
      const hasInvalidTime = this.rows.some((item) => {
        const { items } = item
        return items.some((subItem) => {
          const { startTime, endTime } = subItem
          return startTime < this.startTime || endTime > this.endTime
        })
      })

      if (hasInvalidTime) {
        console.log('时间范围错误,请修改自定义时间')
        return
      }
      const totalWidth = new BigNumber(100)
      const totalMin = new BigNumber(this.totalMin)
      this.perMin = totalWidth.div(totalMin).dp(4).toNumber()
      this.rows.forEach((group) => {
        group.items.forEach((item) => {
          const itemMin = new BigNumber(this.getMinutesBetween(this.startTime, item.startTime))
          const itemWidth = new BigNumber(this.getMinutesBetween(item.startTime, item.endTime))
          const perMin1 = new BigNumber(this.perMin)
          item.totalItemMin = `${itemWidth.toNumber()}`
          item.left = `${itemMin.times(perMin1).dp(4).toNumber()}`
          item.width = `${itemWidth.times(perMin1).dp(4).toNumber()}`
          item.site.forEach((siteItem) => {
            const itemTotalWidth = new BigNumber(100)
            const disMin = new BigNumber(siteItem.disMin)
            siteItem.left = `${itemTotalWidth.div(itemWidth).times(disMin).dp(4).toNumber()}`
          })
        })
      })

      console.log(this.rows)
    },
    // 子块节点的单击
    timeBlock(code, key, item) {
      clearTimeout(this.loop)
      this.loop = setTimeout(() => {
        // 这里执行你自己的方法或者业务逻辑
        console.log(code, key, item, '@子块节点的单击@')
      }, 200)
      // this.iShow = key
      this.stubData = JSON.parse(JSON.stringify(item))
      // 找到对应的节点，根据条件把对应节点打开或者关闭，但是其它节点要全部关闭
      this.rows.map((v, i) => {
        v.items.map((val, j) => {
          if (v.fid === code && j === key) {
            item.changeTimeShow = !item.changeTimeShow
            this.itemStart = item.startTime
            this.itemEnd = item.endTime
          } else {
            this.rows[i].items[j].changeTimeShow = false
          }
        })
      })
      return false
    },
    timedblClick() {
      clearTimeout(this.loop)
      this.dialogVisible = true
      console.log('双点击')
    },
    // 点击时间调整-按钮组
    btns(type, code, key, item, row) {
      if (type === 'cancel') {
        // this.weekList[code].domArr[key] = this.stubData
        item.changeTimeShow = false
        // this.iShow = null
      } else if (type === 'ok') {
        const hasOverlap = this.checkTimeOverlap(row)
        if (hasOverlap) {
          item.startTime = this.stubData.startTime
          item.endTime = this.stubData.endTime
          console.log('时间区间有重叠，报错')
          return
        } else {
          console.log('时间区间无重叠')
        }
        item.changeTimeShow = false
        this.changeEndTime()
        console.log(type, code, key, item, row)
      }
    },

    start(e, val) {
      console.log(e, 'start', val)
      this.baseRows = []
      this.baseRows = JSON.parse(JSON.stringify(val))
    },
    end(val) {
      const aa = this.checkTimeConflicts(this.rows)
      if (aa) {
        this.rows = this.rows.filter(row => row.items.length > 0)
      } else {
        console.log('时间冲突')
        this.rows = this.baseRows
      }
      console.log(this.rows, aa, val)
    },
    onMove(e, originalEvent) {
      console.log(e)
      console.log(originalEvent, 'originalEvent')
      // false表示阻止拖拽
      return true
    },
    clickChoose(e) {
      console.log(e, '鼠标点击选中要拖拽元素')
    },

    // x选定结束时间
    changeEndTime() {
      // const timeArray = this.generateTimeArray(this.startTime, this.endTime)
      const timeArray = this.generateMinTimeArray(this.startTime, this.endTime, '60')
      console.log(timeArray)
      this.totalMin = this.getMinutesBetween(this.startTime, this.endTime)
      this.initData()
      this.timeList = timeArray
    },
    // 每小时 半小时
    timeIntervalchange(e) {
      console.log(e)
      this.timeList = this.generateMinTimeArray(this.startTime, this.endTime, e)
    },
    // 以每分钟生成数组
    generateMinTimeArray(startTime, endTime, min) {
      const interval = Number(min)// 时间间隔为30分钟
      const timeArray = []
      let currentTime = startTime
      while (currentTime <= endTime) {
        timeArray.push(currentTime)
        let [hour, minute] = currentTime.split(':').map(Number)
        minute += interval
        if (minute >= 60) {
          hour += Math.floor(minute / 60)
          minute %= 60
        }
        currentTime = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`
      }
      return timeArray
    },

    // 开始时间到结束时间 算出多少分钟
    getMinutesBetween(startTime, endTime) {
      const startParts = startTime.split(':')
      const endParts = endTime.split(':')
      const startHour = parseInt(startParts[0])
      const startMinute = parseInt(startParts[1])
      const endHour = parseInt(endParts[0])
      const endMinute = parseInt(endParts[1])
      const totalStartMinutes = startHour * 60 + startMinute
      const totalEndMinutes = endHour * 60 + endMinute
      return totalEndMinutes - totalStartMinutes
    },

    // 判断时间区间是否重复[总数组rows]
    checkTimeConflicts(data) {
      // 遍历每个时间段集合
      for (let i = 0; i < data.length; i++) {
        const items1 = data[i].items
        // 遍历该集合中的每个时间段
        for (let j = 0; j < items1.length; j++) {
          const startTime1 = items1[j].startTime
          const endTime1 = items1[j].endTime
          // 再遍历一次集合，但只检查后面的时间段
          for (let k = j + 1; k < items1.length; k++) {
            const startTime2 = items1[k].startTime
            const endTime2 = items1[k].endTime
            // 如果两个时间段有重叠部分，则返回错误信息
            if (
              (startTime1 >= startTime2 && startTime1 < endTime2) ||
          (endTime1 > startTime2 && endTime1 <= endTime2)
            ) {
              console.log(`时间段 ${j + 1} 和时间段 ${k + 1} 存在冲突`)
              return false
            }
          }
        }
      }
      // 时间段没有冲突，返回 null
      return true
    },
    // 判断时间区间是否重复[本身]
    checkTimeOverlap(scheduleArray) {
      for (let i = 0; i < scheduleArray.length - 1; i++) {
        const schedule1 = scheduleArray[i]
        for (let j = i + 1; j < scheduleArray.length; j++) {
          const schedule2 = scheduleArray[j]
          if (
            (schedule2.startTime >= schedule1.startTime && schedule2.startTime <= schedule1.endTime) ||
        (schedule2.endTime >= schedule1.startTime && schedule2.endTime <= schedule1.endTime)
          ) {
            return true // 时间重叠，返回 true
          }
        }
      }
      return false // 没有时间重叠，返回 false
    },
    // 寻找数组中的时间最大值最小值
    checkTime(data) {
      const result = data.reduce((acc, curr) => {
        curr.items.forEach(item => {
          if (!acc.minStartTime || item.startTime < acc.minStartTime) {
            acc.minStartTime = item.startTime
          }
          if (!acc.maxEndTime || item.endTime > acc.maxEndTime) {
            acc.maxEndTime = item.endTime
          }
        })
        return acc
      }, { minStartTime: null, maxEndTime: null })
      console.log('Minimum startTime:', result)
    },
    // 判断数组中的时间值大小
    checkTimeComparison(start, end, arr) {
      arr.forEach(item => {
        const items = item.items
        items.forEach(subItem => {
          const startTime = subItem.startTime
          const endTime = subItem.endTime
          if (startTime < start) {
            this.startTime = startTime
          }
          if (endTime > end) {
            this.endTime = endTime
          }
        })
      })
      console.log(`Start time: ${start}, end time: ${end}`)
    },
    // 跨一天时间生成数组
    generateTimeArray(startTime, endTime, intervalMinutes) {
      // const startDate = new Date('2000-01-01T' + startTime);
      // const endDate = new Date('2000-01-02T' + endTime);
      const startDate = new Date(startTime)
      const endDate = new Date(endTime) // endDate 比 startDate 多了一天
      const intervalMilliseconds = intervalMinutes * 60000
      const result = []
      let currentTime = startDate
      while (currentTime <= endDate) {
        const currentHour = currentTime.getHours().toString().padStart(2, '0')
        const currentMinute = currentTime.getMinutes().toString().padStart(2, '0')
        result.push(currentHour + ':' + currentMinute)
        currentTime = new Date(currentTime.getTime() + intervalMilliseconds)
      }
      return result
    },
    // 开始时间比较结束时间
    startAndend() {
      const startTime = '2023-10-21 08:00'
      const endTime = '2023-10-22 23:00'
      const startDate = new Date(startTime)
      const endDate = new Date(endTime)
      const isCrossDay = startDate.getDate() !== endDate.getDate()
      if (isCrossDay) {
        console.log('开始时间和结束时间跨天')
      } else {
        console.log('开始时间和结束时间不跨天')
      }
    },
    //
    getMinBetween() {
      const startTime = '2023-10-21 08:00'
      const endTime = '2023-10-21 22:00'
      const startDate = new Date(startTime)
      const endDate = new Date(endTime)
      const milliseconds = endDate - startDate
      const minutes = Math.floor(milliseconds / (1000 * 60))
      console.log('时间间隔为：', minutes, '分钟')
    }

  }
}
</script>
<style scoped lang="scss">
.sortable{
  // width: 810px;
  width: 100%;
  display: flex;
  align-items: end;
  background: red;
  margin-bottom: 8px;
  padding: 5px;
}
.sortable-list{
  height: 100%;
  background: grey;
  padding: 5px 15px;
}
.row-item{
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  box-flex: 1
}
// 刻度
.slide-ruler {
  position: relative;
  left: 0px;
  // width: 730px;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-left:28px ;
  padding-right: 20px;
}
.slide-ruler-item {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: 0px;
  // width: 730px;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 99;
}
.scale {
  text-align: center;
  width: 15px;
  font-size: 12px;
}
.scale-item {
  text-align: center;
  width: 2px;
  height: 18px;
  border-radius: 9px;
  background: #008B8B;
}
.slide-list {
  // width: 720px;
  position: relative;
  width: 100%;
}
.slide-box {
  width: 100%;
  height: 20px;
  background: 	#483D8B;
  display: flex;
  position: relative;
}
.slide-box-item {
  height: 100%;
  position: absolute;
  z-index: 999;
  padding: 0 5px;
  box-sizing: border-box;
  cursor: pointer;
}
.mover-item{
  display: inline-block;
  width: 100%;
  height: 20px;
  position: relative;
  display: flex;
  align-items: center;
}
.mover-item-site{
  position: absolute;
  width: 10px;
  height: 10px;
  background: green;
}
.i-class{
  width: 20px;
  height: 20px;
  position: absolute;
  display: inline-block;
  background: greenyellow;
  background-position: -5px;
  z-index: 1;
}
.i-left-class{
  left: -3px;
}
.i-right-class{
  right: -3px;
}
.i-class:hover{
  cursor:w-resize
}
.timeHover {
  width: 100%;
  height: 100%;
  display: inline-block;
}

</style>
